﻿using Coldairarrow.Entity.BackStage.ConsumeChats;
using Coldairarrow.Entity.Base_Manage;
using Coldairarrow.Entity.BTB_StaffUsers;
using Coldairarrow.IBusiness.BTB_StaffUsers;
using Coldairarrow.Util;
using Coldairarrow.Util.DTO.OnlineChat;
using EFCore.Sharding;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.SignalR;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Caching.Distributed;
using Microsoft.Extensions.DependencyInjection;
using Newtonsoft.Json;
using Serilog;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Lucene.Net.Analysis;
using Lucene.Net.Analysis.PanGu;
using Nest;
using Elasticsearch.Service;
using Coldairarrow.Entity.Base_AutoReplys;
using System.IO;
using System.Text.RegularExpressions;
using Coldairarrow.Entity.FrontStage.UserData;
using Coldairarrow.Business.TRTC;
using Coldairarrow.IBusiness;

namespace Coldairarrow.Business.BTB_StaffUsers
{
    class UserOnlineChatBusiness : BaseBusiness<ChatRoom>, IUserOnlineChatBusiness, ITransientDependency
    {
        private readonly IHubContext<MessageHub> _messageHub;
        readonly IOperator _operator;
        private readonly ElasticClient _client;
        readonly IServiceProvider _serviceProvider;
        static string IFName = "qlautoreply";
        readonly string userDefaultHeadImg = "http://qnmzptapi.xazkrj.cn/Upload/HeadPort/dhead.jpg";
        readonly string KfDefaultHeadImg = "/HeadImg/kefu002.png";
        public UserOnlineChatBusiness(IDbAccessor db, IOperator @operator, IHubContext<MessageHub> messageHub, IServiceProvider serviceProvider, IEsClientProvider clientProvider)
           : base(db)
        {
            _serviceProvider = serviceProvider;
            _messageHub = messageHub;
            _operator = @operator;
            _client = clientProvider.GetClient();
        }

        /// <summary>
        /// 获取未登录用户UserId
        /// </summary>
        /// <returns></returns>
        public object GetRUserId()
        {
            string userId = "", userName = "", headImg = "";
            int hType = 0;
            if (_operator.IsNullOrEmpty() || _operator.UserId.IsNullOrEmpty())
            {
                userId = GetUserId();
                userName = "游客"+ userId.Substring(userId.Length - 5);
                headImg = userDefaultHeadImg;
                hType = 1;
            }
            else
            {
                userId = _operator.UserId;
                var uModel = Service.GetIQueryable<BTB_StaffUser>().Where(s => s.id.Equals(userId)).FirstOrDefault();
                if (uModel.IsNullOrEmpty())
                {
                    userName = "游客"+ userId.Substring(userId.Length - 5);
                    headImg = userDefaultHeadImg;
                    hType = 1;
                }
                else
                {
                    userName = uModel.NickName;
                    headImg = uModel.HeadPortrait.IsNullOrEmpty() ? userDefaultHeadImg: uModel.HeadPortrait;
                    hType = uModel.HeadPortrait.IsNullOrEmpty() ? 1 : uModel.HeadType.Value;
                } 
            }

            var obj = new {
                UserId = userId,
                HeadImg = headImg,
                HeadType = hType,
                UserName = userName
            };

            return obj;
        }

        /// <summary>
        /// 用户加入房间列表
        /// </summary>
        /// <param name="input">平台类型</param>
        /// <returns></returns>
        /// <exception cref="BusException"></exception>
        public async Task<GetRoomDTO>  UserToRoomAsync(UserToRoomDTO input)
        {
            Log.Information("用户加入房间传参 ===》 input ==> " + input.ToJson());

            string userId = "",userName = "",csId = "";
            //用户未登录
            if (!_operator.IsNullOrEmpty() && !_operator.UserId.IsNullOrEmpty())
            {
                userId = _operator.UserId;
                var uModel = Service.GetIQueryable<BTB_StaffUser>().Where(m => m.id.Equals(userId)).FirstOrDefault();
                if (!uModel.IsNullOrEmpty())
                {
                    userName = uModel.NickName;
                }
            }
            else if (!input.UserId.IsNullOrEmpty())
            {
                userId = input.UserId;
                userName = "游客"+ userId.Substring(userId.Length - 6);
            }
            else
            {
                throw new BusException("传入参数错误，请重试！");
            }

            GetRoomDTO res = new GetRoomDTO();

            #region//获取用户房间信息
            var sfrModel = await (from a in Service.GetIQueryable<ChatRoom>().Where(m => m.UserId.Equals(userId))
                            join b in Service.GetIQueryable<ChatRoomCSUser>().Where(s => s.State == true) on a.Id equals b.RoomId
                            join j in Service.GetIQueryable<ConsumeServer>().Where(h => h.ClassId == input.Class && h.State == true) on b.ConstmeServerId equals j.UserId
                            join h in Service.GetIQueryable<Base_User>() on j.UserId equals h.Id
                            select new
                            {
                                a.Id,
                                CSId = b.ConstmeServerId
                            }).FirstOrDefaultAsync();

            if (sfrModel.IsNullOrEmpty())
            {
                #region//获取在线客服信息
                List<OnLinkUserDTO> csList = new List<OnLinkUserDTO>();
                var cache = _serviceProvider.GetService<IDistributedCache>();
                var jstr = cache.GetString("OLinkUserList");
                if (!jstr.IsNullOrEmpty())
                {
                    csList = JsonConvert.DeserializeObject<List<OnLinkUserDTO>>(jstr);

                }
                else
                {
                    csList = new List<OnLinkUserDTO>();
                }

                List<string> uIds = csList.Where(m => m.UserType == 1 && m.Class == input.Class).Select(x => x.UserId).ToList();

                //获取客服列表
                List<CServiceDTO> cList = new List<CServiceDTO>();
                var cstr = cache.GetString("OCSUserList");
                if (!cstr.IsNullOrEmpty())
                {
                    cList = JsonConvert.DeserializeObject<List<CServiceDTO>>(cstr);
                }
                else
                {
                    cList = new List<CServiceDTO>();
                }

                if (uIds.Count == 0)
                {
                    uIds = cList.Where(s => s.ClassId == input.Class).Select(m => m.Id).Distinct().ToList();
                }
                #endregion

                #region//获取房间信息
                var srModel = await (from a in Service.GetIQueryable<ChatRoom>().Where(x => x.UserId.Equals(userId) && x.ClassId.Equals(input.Class))
                                     join k in Service.GetIQueryable<ChatRoomCSUser>().Where(m => m.State == true) on a.Id equals k.RoomId 
                                     join j in Service.GetIQueryable<ConsumeServer>().Where(h => h.ClassId == input.Class && h.State == true) on k.ConstmeServerId equals j.UserId
                                     join h in Service.GetIQueryable<Base_User>() on j.UserId equals h.Id
                                     select new
                                     {
                                         RId = a.Id,
                                         RName = a.ChatRoot_Name,
                                         SId = k.ConstmeServerId
                                     }).FirstOrDefaultAsync();

                if (srModel.IsNullOrEmpty())
                {
                    var uId = await GetCSUserId(uIds, input.Class);
                    csId = uId;
                    if (!uId.IsNullOrEmpty())
                    {

                        #region//创建聊天房间
                        ChatRoom rModel = new ChatRoom();
                        rModel.Id = IdHelper.GetId();
                        rModel.CreatorId = userId;
                        rModel.CreateTime = DateTime.Now;
                        rModel.Deleted = false;
                        rModel.UserId = userId;
                        rModel.ClassId = input.Class;
                        rModel.ChatRoot_Name = "在线客服";
                        rModel.State = true;

                        //加入客服
                        ChatRoomCSUser csUser = new ChatRoomCSUser();
                        csUser.Id = IdHelper.GetId();
                        csUser.CreatorId = userId;
                        csUser.CreateTime = DateTime.Now;
                        csUser.Deleted = false;
                        csUser.RoomId = rModel.Id;
                        csUser.ConstmeServerId = uId;
                        csUser.StartTime = csUser.CreateTime;
                        csUser.State  = true;

                        await Service.InsertAsync(rModel);
                        await Service.InsertAsync(csUser);

                        res.Id =  rModel.Id;
                        res.CSId = "CS" + csId;
                        res.ChatRoot_Name = rModel.ChatRoot_Name;

                        #endregion
                    }
                    else
                    {
                        throw new BusException("后台未配置客服，请联系管理员！");
                    }
                }
                else if (srModel.SId.IsNullOrEmpty())
                {

                    var uId = await GetCSUserId(uIds, input.Class);
                    csId = uId;
                    if (!uId.IsNullOrEmpty())
                    {
                        //加入客服
                        ChatRoomCSUser csUser = new ChatRoomCSUser();
                        csUser.Id = IdHelper.GetId();
                        csUser.CreatorId = userId;
                        csUser.CreateTime = DateTime.Now;
                        csUser.Deleted = false;
                        csUser.RoomId = srModel.RId;
                        csUser.ConstmeServerId = uId;
                        csUser.StartTime = csUser.CreateTime;
                        csUser.State  = true;

                        await Service.InsertAsync(csUser);

                        res.Id =  srModel.RId;
                        res.ChatRoot_Name = srModel.RName;
                    }
                    else
                    {
                        throw new BusException("后台未配置客服，请联系管理员！");
                    }
                }
                else
                {
                    csId = srModel.SId;
                    res.Id =  srModel.RId;
                    res.ChatRoot_Name = srModel.RName;
                }
                #endregion

                #region//向用户/客服发送进入房间消息
                //向客服发送消息
                ChatContent scModel = new ChatContent();
                scModel.Id = IdHelper.GetId();
                scModel.CreatorId = "";
                scModel.CreateTime = DateTime.Now;
                scModel.Deleted = false;
                scModel.MessageType = 10;
                scModel.MessageContent = "用户"+userName+"进入聊天!";
                scModel.RoomId = res.Id;
                scModel.ReadState = false;
                scModel.SenderId = "";
                scModel.ReceiverId = csId;
                scModel.SenderType = 1;
                scModel.MassageName = "";
                scModel.MessageSize = "";
                scModel.VState = false;

                await Service.InsertAsync(scModel);
                //用户消息
                ChatContent ucModel = new ChatContent();
                ucModel.Id = IdHelper.GetId();
                ucModel.CreatorId = "";
                ucModel.CreateTime = DateTime.Now;
                ucModel.Deleted = false;
                ucModel.MessageType = 10;
                ucModel.MessageContent = "您已进入聊天房间!";
                ucModel.RoomId = res.Id;
                ucModel.MessageType = 10;
                ucModel.ReadState = false;
                ucModel.SenderId = "";
                ucModel.ReceiverId = userId;
                ucModel.SenderType = 1;
                ucModel.MassageName = "";
                ucModel.MessageSize = "";
                ucModel.VState = false;

                await Service.InsertAsync(ucModel);

                #endregion

                #region//刷新消息提示
                var isTheRoom = false;
                var rcsModel = cList.Where(m => m.Id.Equals(csId) && m.ClassId.Equals(input.Class)).FirstOrDefault();
                if (rcsModel.IsNullOrEmpty())
                {
                    CServiceDTO rcModel = new CServiceDTO();
                    rcModel.Id = csId;
                    rcModel.ClassId = input.Class;
                    rcModel.OnChatRoomId = "";

                    cList.Add(rcModel);
                    cache.SetString("OCSUserList", cList.ToJson().ToString());
                }
                else
                {

                    //判断当前聊天人是否此用户
                    if (rcsModel.OnChatRoomId.Equals(res.Id))
                    {
                        isTheRoom = true;
                    }
                }

                var TOLCService = csList.Where(x => x.UserId.Equals(csId) && x.Class == input.Class).FirstOrDefault();
                if (!isTheRoom && TOLCService.IsNullOrEmpty())
                {
                    //刷新当前房间客服未读消息
                    await UpdateCSMessageList(csId, input.Class, res.Id, "");
                }

                //刷新客服房间未读消息数量
                await SendCSUnReadNum(csId, input.Class);

                //刷新客服房间列表
                await UpdateCSRoomList(csId, input.Class);

                //刷新用户未读消息数量
                await SendCUnReadNum(csId, input.Class, res.Id);

                //刷新用户房间消息
                await UpdateCUMessageList(csId, input.Class, res.Id);
                #endregion
            }
            else
            {
                res.Id = sfrModel.Id;
                res.CSId = "CS" + sfrModel.CSId;
                res.ChatRoot_Name = "在线客服";
            }

            #endregion

            return res;
        }

        /// <summary>
        /// 用户发送消息
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        /// <exception cref="BusException"></exception>
        public async Task UserSendMessageAsync(UserSendChatDTO input)
        {
            #region//获取房间信息
            var rModel = await Service.GetIQueryable<ChatRoom>().Where(m => m.Id.Equals(input.roomId)).FirstOrDefaultAsync();
            if (!rModel.IsNullOrEmpty())
            {
                string consumeServiceId = ""; //客服Id

                #region//获取在线客服信息
                GetRoomDTO res = new GetRoomDTO();
                List<OnLinkUserDTO> csList = new List<OnLinkUserDTO>();
                var cache = _serviceProvider.GetService<IDistributedCache>();
                var jstr = cache.GetString("OLinkUserList");
                if (!jstr.IsNullOrEmpty())
                {
                    csList = JsonConvert.DeserializeObject<List<OnLinkUserDTO>>(jstr);

                }
                else
                {
                    csList = new List<OnLinkUserDTO>();
                }

                List<string> uIds = csList.Where(m => m.UserType == 1 && m.Class == rModel.ClassId).Select(x => x.UserId).ToList();

                //获取客服列表
                List<CServiceDTO> cList = new List<CServiceDTO>();
                var cstr = cache.GetString("OCSUserList");
                if (!cstr.IsNullOrEmpty())
                {
                    cList = JsonConvert.DeserializeObject<List<CServiceDTO>>(cstr);
                }
                else
                {
                    cList = new List<CServiceDTO>();
                }
                #endregion

                #region//获取房间客服信息
                var csmModel = await (from a in Service.GetIQueryable<ChatRoom>().Where(m => m.Id.Equals(input.roomId))
                               join b in Service.GetIQueryable<ChatRoomCSUser>().Where(m => m.State == true) on a.Id equals b.RoomId
                               join j in Service.GetIQueryable<ConsumeServer>().Where(h => h.ClassId == rModel.ClassId) on b.ConstmeServerId equals j.UserId
                               join k in Service.GetIQueryable<Base_User>() on j.UserId equals k.Id
                               select k).FirstOrDefaultAsync();

                if (!csList.IsNullOrEmpty())
                {
                    consumeServiceId = csmModel.Id;

                }
                else
                {
                    consumeServiceId = await GetCSUserId(uIds, rModel.ClassId);

                    //给房间加入新客服
                    ChatRoomCSUser csUser = new ChatRoomCSUser();
                    csUser.Id = IdHelper.GetId();
                    csUser.CreatorId = rModel.UserId;
                    csUser.CreateTime = DateTime.Now;
                    csUser.Deleted = false;
                    csUser.RoomId = rModel.Id;
                    csUser.ConstmeServerId = consumeServiceId;
                    csUser.StartTime = csUser.CreateTime;
                    csUser.State  = true;

                    await Service.InsertAsync(csUser);
                }
                #endregion

                #region//向客服发送用户消息
                //向客服发送消息
                ChatContent scModel = new ChatContent();
                scModel.Id = IdHelper.GetId();
                scModel.CreatorId = "";
                scModel.CreateTime = DateTime.Now;
                scModel.Deleted = false;
                scModel.MessageType = input.messageType;
                scModel.MessageContent = input.messageContent;
                scModel.RoomId = input.roomId;
                scModel.ReadState = false;
                scModel.SenderId = rModel.UserId;
                scModel.ReceiverId = consumeServiceId;
                scModel.SenderType = 0;
                scModel.MassageName = input.messageName;
                scModel.MessageSize = input.messageSize;
                scModel.VState = input.vstate.HasValue? input.vstate:false;

                await Service.InsertAsync(scModel);

                //更新用户消息为已读
                await Service.UpdateAsync<ChatContent>(x => x.ReceiverId.Equals(rModel.UserId) && x.RoomId.Equals(rModel.Id) && x.ReadState == false, m => m.ReadState = true);

                #region//判断插入每日聊天记录表
                var theTime = DateTime.Parse(DateTime.Now.ToString("yyyy-MM-dd"));
                var aCount = Service.GetIQueryable<UserChatLog>().Where(s => s.UserId.Equals(rModel.UserId) && s.ChatDate == theTime).Count();
                if (aCount == 0)
                {
                    UserChatLog uclModel = new UserChatLog();
                    uclModel.Id = IdHelper.GetId();
                    uclModel.UserId = rModel.UserId;
                    uclModel.CreateTime = DateTime.Now;
                    uclModel.ChatDate = theTime;

                    await Service.InsertAsync(uclModel);
                }
                #endregion

                #endregion

                #region//判断是否自动回复
                string sId = "";
                var sfModel = csList.Where(x => x.UserId.Equals(consumeServiceId) && x.UserType == 1 && x.Class.Equals(rModel.ClassId)).FirstOrDefault();
                var mstr = sfModel.IsNullOrEmpty() ? "{}" : sfModel.ToJson();
                Log.Information("UserId={0},csList.count={1},rModel.ClassId={2},sModel={3}", consumeServiceId, csList.Count, rModel.ClassId, mstr);
                if (sfModel.IsNullOrEmpty())
                {
                    ReplayInputDTO ipt = new ReplayInputDTO();
                    ipt.ChatLog_RoomId = rModel.Id;
                    ipt.ChatLog_Content = input.messageContent;
                    ipt.ChatRoot_StaffId = consumeServiceId;
                    ipt.ChatRoot_UserId =  rModel.UserId;
                    ipt.ClassId = rModel.ClassId;

                    //客服不在线开启自动回复
                    if (input.messageContent.Equals("#"))
                    {
                        var dmData = ASTDTO.ASTList.Find(x => x.UserId.Equals(_operator.UserId) && x.StaffId.Equals(consumeServiceId));
                        if (dmData.IsNullOrEmpty())
                        {
                            await JQRAutoReply(ipt, "");
                        }
                        else
                        {
                            ChatContent tscModel = new ChatContent();
                            tscModel.Id = IdHelper.GetId();
                            tscModel.CreatorId = "";
                            tscModel.CreateTime = DateTime.Now;
                            tscModel.Deleted = false;
                            tscModel.MessageType = 11;
                            tscModel.MessageContent =  dmData.ATId;
                            tscModel.RoomId = rModel.Id;
                            tscModel.ReadState = false;
                            tscModel.SenderId = consumeServiceId;
                            tscModel.ReceiverId = _operator.UserId;
                            tscModel.SenderType = 1;
                            tscModel.MassageName = "";
                            tscModel.MessageSize = "";
                            tscModel.VState = true;

                            await Service.InsertAsync(tscModel);

                            sId = tscModel.Id;
                            #region//刷新用户和客服房间消息

                            //刷新用户消息列表
                            await SendCUnReadNum(_operator.UserId, rModel.ClassId, rModel.Id);

                            //刷新用户房间消息列表
                            await UpdateCUMessageList(_operator.UserId, rModel.ClassId, rModel.Id);
                            #endregion
                        }
                    }
                    else
                    {
                        //引用正则表达式类
                        Regex reg = new Regex("^[0-9]+$");
                        Match ma = reg.Match(input.messageContent);
                        var dmData = ASTDTO.ASTList.Find(x => x.UserId.Equals(rModel.UserId) && x.StaffId.Equals(consumeServiceId));
                        if (ma.Success && !dmData.IsNullOrEmpty() && dmData.ATDId.Count > 0)
                        {
                            int index = Int32.Parse(input.messageContent);
                            if (index > dmData.ATDId.Count)
                            {
                                ChatContent tscModel = new ChatContent();
                                tscModel.Id = IdHelper.GetId();
                                tscModel.CreatorId = "";
                                tscModel.CreateTime = DateTime.Now;
                                tscModel.Deleted = false;
                                tscModel.MessageType = 0;
                                tscModel.MessageContent =   "抱歉，您回复的数字有误，请重新输入对应序号！";
                                tscModel.RoomId = rModel.Id;
                                tscModel.ReadState = false;
                                tscModel.SenderId = consumeServiceId;
                                tscModel.ReceiverId = rModel.UserId;
                                tscModel.SenderType = 1;
                                tscModel.MassageName = "";
                                tscModel.MessageSize = "";
                                tscModel.VState = true;

                                await Service.InsertAsync(tscModel);

                                sId = tscModel.Id;
                                #region//刷新用户和客服房间消息

                                //刷新用户消息列表
                                await SendCUnReadNum(rModel.UserId, rModel.ClassId, rModel.Id);

                                //刷新用户房间消息列表
                                await UpdateCUMessageList(rModel.UserId, rModel.ClassId, rModel.Id);
                                #endregion

                            }
                            else
                            {
                                ChatContent tscModel = new ChatContent();
                                tscModel.Id = IdHelper.GetId();
                                tscModel.CreatorId = "";
                                tscModel.CreateTime = DateTime.Now;
                                tscModel.Deleted = false;
                                tscModel.MessageType = 12;
                                tscModel.MessageContent =  dmData.ATDId[index - 1];
                                tscModel.RoomId = rModel.Id;
                                tscModel.ReadState = false;
                                tscModel.SenderId = consumeServiceId;
                                tscModel.ReceiverId = rModel.UserId;
                                tscModel.SenderType = 1;
                                tscModel.MassageName = "";
                                tscModel.MessageSize = "";
                                tscModel.VState = true;

                                await Service.InsertAsync(tscModel);

                                sId = tscModel.Id;

                                #region//刷新用户和客服房间消息

                                //刷新用户消息列表
                                await SendCUnReadNum(rModel.UserId, rModel.ClassId, rModel.Id);

                                //刷新用户房间消息列表
                                await UpdateCUMessageList(rModel.UserId, rModel.ClassId, rModel.Id);
                                #endregion
                            }

                        }
                        else if (!ma.Success)
                        {
                            await JQRAutoReply(ipt, "");
                        }
                        else
                        {

                            ChatContent tscModel = new ChatContent();
                            tscModel.Id = IdHelper.GetId();
                            tscModel.CreatorId = "";
                            tscModel.CreateTime = DateTime.Now;
                            tscModel.Deleted = false;
                            tscModel.MessageType = 0;
                            tscModel.MessageContent =   "抱歉无法理解您输入的问题，麻烦请换个问题重试提问！";
                            tscModel.RoomId = rModel.Id;
                            tscModel.ReadState = false;
                            tscModel.SenderId = consumeServiceId;
                            tscModel.ReceiverId = rModel.UserId;
                            tscModel.SenderType = 1;
                            tscModel.MassageName = "";
                            tscModel.MessageSize = "";
                            tscModel.VState = true;

                            await Service.InsertAsync(tscModel);

                            sId = tscModel.Id;

                            #region//刷新用户和客服房间消息

                            //刷新用户消息列表
                            await SendCUnReadNum(rModel.UserId, rModel.ClassId, rModel.Id);

                            //刷新用户房间消息列表
                            await UpdateCUMessageList(rModel.UserId, rModel.ClassId, rModel.Id);
                            #endregion
                        }

                    }
                }
                #endregion

                #region//判断是否客服和此用户
                var isTheRoom = false;
                var rcsModel = cList.Where(m => m.Id.Equals(consumeServiceId) && m.ClassId.Equals(rModel.ClassId)).FirstOrDefault();
                if (rcsModel.IsNullOrEmpty())
                {
                    CServiceDTO rcModel = new CServiceDTO();
                    rcsModel.Id = consumeServiceId;
                    rcsModel.ClassId = rModel.ClassId;
                    rcsModel.OnChatRoomId = "";

                    cList.Add(rcsModel);
                    cache.SetString("OCSUserList", cList.ToJson().ToString());
                }
                else
                {

                    //判断当前聊天人是否此用户
                    if (rcsModel.OnChatRoomId.Equals(input.roomId))
                    {
                        isTheRoom = true;
                    }
                }

                var TOLCService = csList.Where(x => x.UserId.Equals(consumeServiceId) && x.Class == rModel.ClassId).FirstOrDefault();
                if (isTheRoom && !TOLCService.IsNullOrEmpty())
                {
                    //刷新当前房间客服未读消息
                    await UpdateCSMessageList(consumeServiceId, rModel.ClassId, input.roomId, sId);
                }
                #endregion

                //刷新客服房间未读消息数量
                await SendCSUnReadNum(consumeServiceId, rModel.ClassId);

                //刷新客服房间列表
                await UpdateCSRoomList(consumeServiceId, rModel.ClassId);

                //更新用户已读消息数量
                await SendCUnReadNum(consumeServiceId, rModel.ClassId, input.roomId);
            }
            else
            {
                throw new BusException("获取房间失败，发送消息失败！");
            }

            #endregion

        }

        /// <summary>
        /// 用户获取未读消息数量
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        /// <exception cref="BusException"></exception>
        public async Task UserGetUnReadCountAsync(UserToRoomDTO input)
        {
            string userId = "";
            if (!_operator.IsNullOrEmpty() && !_operator.UserId.IsNullOrEmpty())
            {
                userId = _operator.UserId;
            }
            else if (!input.UserId.IsNullOrEmpty())
            {
                userId = input.UserId;
            }

            if (!userId.IsNullOrEmpty())
            {
                //获取房间Id
                var rModel = await Service.GetIQueryable<ChatRoom>().Where(m => m.ClassId == input.Class && m.UserId.Equals(userId)).FirstOrDefaultAsync();
                if (rModel.IsNullOrEmpty())
                {
                    await UpdateCUMessageList(userId, input.Class, "");
                }
                else
                {
                    await UpdateCUMessageList(userId, rModel.ClassId, rModel.Id);
                }
            }
            else
            {
                throw new BusException("参数错误，获取信息失败！");
            }

        }

        /// <summary>
        /// 用户获取聊天记录列表
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<ChatLogListDTO> GetUserMessageLogAsync(GetMassageDTO input)
        {
            ChatLogListDTO res = new ChatLogListDTO();
            Log.Information("进入获取聊天记录列表");
            ChatLogListDTO data = new ChatLogListDTO();
            string userId = "";
            if (!_operator.IsNullOrEmpty() && !_operator.UserId.IsNullOrEmpty())
            {
                userId = _operator.UserId;
            }
            else if(!input.userId.IsNullOrEmpty())
            {
                userId = input.userId;
            }


            if (!userId.IsNullOrEmpty() && !input.roomId.IsNullOrEmpty())
            {
                Log.Information("记录列表 userId = " + userId);
                var rModel = Service.GetIQueryable<ChatRoom>().Where(m => m.Id.Equals(input.roomId)).FirstOrDefault();
                if (!rModel.IsNullOrEmpty())
                {
                    DateTime StartTime = new DateTime();
                    if (input.stime.HasValue)
                    {
                        StartTime = input.stime.Value;
                    }
                    else
                    {
                        StartTime = DateTime.Now;
                    }

                    #region//初始参数配置
                    if (input.page <= 0)
                    {
                        input.page = 1;
                    }

                    if (input.row <= 0)
                    {
                        input.row = 10;
                    }
                    #endregion

                    res.MCount = Service.GetIQueryable<ChatContent>().Where(m => ((m.MessageType == 10 && m.ReceiverId.Equals(rModel.UserId)) || m.MessageType != 10)&& m.RoomId.Equals(input.roomId) && m.CreateTime <= StartTime).Count();

                    //获取消息记录
                    var msList = Service.GetIQueryable<ChatContent>().Where(m =>((m.MessageType == 10 && m.ReceiverId.Equals(rModel.UserId)) || m.MessageType != 10)&& m.RoomId.Equals(input.roomId) && m.CreateTime <= StartTime).OrderByDescending(m => m.CreateTime).Skip(input.row * (input.page - 1)).Take(input.row).ToList();

                    res.MList = new List<ChatLogDTO>();
                    foreach (var item in msList)
                    {
                        ChatLogDTO mModel = new ChatLogDTO();
                        mModel.Id = item.Id;
                        if (userId.Equals(item.SenderId) && item.SenderType == 0)
                        {
                            mModel.userType  = 0;
                            var uModel = await Service.GetIQueryable<BTB_StaffUser>().Where(m => m.id.Equals(userId)).FirstOrDefaultAsync();
                            if (uModel != null)
                            {
                                mModel.headPortrait = uModel.HeadPortrait.IsNullOrEmpty() ? userDefaultHeadImg : uModel.HeadPortrait;
                                mModel.headImgType = uModel.HeadPortrait.IsNullOrEmpty() ? 1 : uModel.HeadType.Value ;
                                mModel.nickName = uModel.NickName;
                                mModel.nickNames = uModel.NickName;
                            }
                            else
                            {
                                mModel.headPortrait = userDefaultHeadImg;
                                mModel.headImgType = 1;
                                mModel.nickName = "游客" + userId.Substring(userId.Length - 5);
                                mModel.nickNames ="游客" + userId.Substring(userId.Length - 5);
                            }

                        }
                        else
                        {
                            mModel.userType  = 1;
                            var csMdoel = await (from a in Service.GetIQueryable<Base_User>().Where(x => x.Id.Equals(item.SenderId))
                                                 join b in Service.GetIQueryable<ConsumeServer>() on a.Id equals b.UserId into ab
                                                 from b in ab.DefaultIfEmpty()
                                                 select new
                                                 {
                                                     a.Id,
                                                     a.RealName,
                                                     b.HeadImg,
                                                     HeadType = 0
                                                 }).FirstOrDefaultAsync();

                            if (!csMdoel.IsNullOrEmpty())
                            {
                                var sPath = GetServicePath();
                                mModel.headPortrait = sPath + "/" + (csMdoel.HeadImg.IsNullOrEmpty() ? KfDefaultHeadImg : csMdoel.HeadImg);
                                mModel.headImgType = 1;
                                mModel.nickName = csMdoel.RealName;
                                mModel.nickNames = csMdoel.RealName;
                            }
                            else
                            {
                                var sPath = GetServicePath();
                                mModel.headPortrait = sPath + "/" + KfDefaultHeadImg;
                                mModel.headImgType = 1;
                                mModel.nickName = "客服" + userId.Substring(userId.Length - 5);
                                mModel.nickNames ="客服" + userId.Substring(userId.Length - 5);
                            }
                        }

                        mModel.messageContent = item.MessageContent;
                        mModel.messageType = item.MessageType;

                        //自动回复整理内容
                        if (mModel.messageType == 11 && !item.MessageContent.IsNullOrEmpty())
                        {
                            var rpModel = (from a in Service.GetIQueryable<Base_AutoReply>().Where(s => s.Id.Equals(item.MessageContent))
                                           select new AutoReplyDTO
                                           {
                                               id = a.Id,
                                               contents = a.Contents,
                                               imgURL = a.ImgURL,
                                               link = a.ImgURL,
                                               childList = (from b in Service.GetIQueryable<Base_AutoReplyDetail>(true).Where(s => s.ReplyId.Equals(a.Id))
                                                            select new ReplyDetailDTO
                                                            {
                                                                id = b.Id,
                                                                contents = b.KeyNum,
                                                                imgURL = b.ImgUrl,
                                                                link = b.LinkUrl
                                                            }).ToList()
                                           }).FirstOrDefault();
                            if (!rpModel.IsNullOrEmpty())
                            {
                                mModel.auto_Model = rpModel;
                            }


                        }
                        else if (mModel.messageType == 12 && !item.MessageContent.IsNullOrEmpty())
                        {
                            var dtMdoel = Service.GetIQueryable<Base_AutoReplyDetail>().Where(x => x.Id.Equals(item.MessageContent)).Select(s => new Base_AutoReplyDetailDTO
                            {
                                id = s.Id,
                                createTime = s.CreateTime,
                                replyId = s.ReplyId,
                                contents = s.Contents
                            }).FirstOrDefault();
                            if (!dtMdoel.IsNullOrEmpty())
                            {
                                mModel.detailModel = dtMdoel;
                            }
                            else
                            {
                                mModel.messageType = 0;
                                mModel.messageContent = "抱歉，未找到对应内容";
                                Service.Update(mModel);
                            }
                        }
                        mModel.createTime = item.CreateTime;
                        mModel.createTimes = item.CreateTime.ToString("yyyy年MM月dd日 HH:mm:ss");
                        mModel.messageSize = item.MessageSize;
                        mModel.messageName = item.MassageName;
                        mModel.vstate = item.VState;

                        res.MList.Add(mModel);

                        //修改未读为已读
                        if (item.ReadState == false)
                        {
                            item.ReadState = true;
                            await Service.UpdateAsync(item);
                        }
                    }

                    await UpdateCUMessageList(userId,rModel.ClassId,rModel.Id);
                }
                else
                {
                    res.MCount = 0;
                    res.MList = new List<ChatLogDTO>();
                }
               
            }
            else
            {
                res.MCount = 0;
                res.MList = new List<ChatLogDTO>();
            }

           

            return res;
        }

        #region//webRTC
        /// <summary>
        /// 获取用户Id和名称
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<PTUDTO> GetUserDataAsnyc(GTUDTO input)
        {
            PTUDTO model = new PTUDTO();
            model.SDKAppId = GenerateTestUserSig.SDKAPPID;
            string userId = "";
            int type = 0;
            if (!_operator.IsNullOrEmpty() && !_operator.UserId.IsNullOrEmpty())
            {
                userId = _operator.UserId;
            }
            else if (!input.UserId.IsNullOrEmpty() && input.Type == 0)
            {
                userId = input.UserId;
                type = 1;
            }
            else
            {
                throw new BusException("token验证失败！",401);
            }

            if (!userId.IsNullOrEmpty())
            {
                if (input.Type == 0)
                {
                    //用户信息
                    if (type == 0)
                    {
                        var userModel = await Service.GetIQueryable<BTB_StaffUser>().Where(s => s.id.Equals(input.UserId)).FirstOrDefaultAsync();
                        if (!userModel.IsNullOrEmpty())
                        {
                            model.MUserId = "USE" + userModel.id;
                            model.MUserSign = GetUserSign(model.MUserId);
                            model.MUserHeadImg = userModel.HeadPortrait;
                            model.MUserHeadType = userModel.HeadType;
                            model.MUserName = userModel.NickName;
                        }
                        else
                        {
                            model.MUserId = "USE" + userId;
                            model.MUserSign = GetUserSign(model.MUserId);
                            model.MUserHeadImg = userDefaultHeadImg;
                            model.MUserHeadType = 1;
                            model.MUserName = "游客" + userId.Substring(userId.Length - 5);
                        }
                       
                    }
                    else
                    {
                        model.MUserId = "USE" + userId;
                        model.MUserSign = GetUserSign(model.MUserId);
                        model.MUserHeadImg = userDefaultHeadImg;
                        model.MUserHeadType = 1;
                        model.MUserName = "游客" + userId.Substring(userId.Length - 5);
                    }
                }
                else if(input.Type == 1)
                {

                   var csModel = await (from a in Service.GetIQueryable<Base_User>().Where(s => s.Id.Equals(userId))
                                   join b in Service.GetIQueryable<ConsumeServer>() on a.Id equals b.UserId into ab
                                   from b in ab.DefaultIfEmpty()
                                   select new
                                     {
                                         a.Id,
                                         b.HeadImg,
                                         a.RealName
                                     }).FirstOrDefaultAsync();

                    if (!csModel.IsNullOrEmpty())
                    {
                        var sPath = GetServicePath();
                        model.MUserId = "CS" + userId;
                        model.MUserSign = GetUserSign(model.MUserId);
                        model.MUserHeadImg = sPath + "/" + csModel.HeadImg;
                        model.MUserHeadType = 1;
                        model.MUserName = csModel.RealName;
                    }
                    else
                    {
                        var sPath = GetServicePath();
                        model.MUserId = "CS" + userId;
                        model.MUserSign = GetUserSign(model.MUserId);
                        model.MUserHeadImg =  sPath + "/" + KfDefaultHeadImg;
                        model.MUserHeadType = 1;
                        model.MUserName = "客服" + userId.Substring(userId.Length - 5);
                    }
                }
            }
            else
            {
                throw new BusException("参数错误，获取信息失败！");
            }

            return model;
        }

        /// <summary>
        /// 获取用户签名
        /// </summary>
        /// <returns></returns>
        private string GetUserSign(string userId)
        {
            string data = "";
            if (!userId.IsNullOrEmpty() && userId != null)
            {
                data = GenerateTestUserSig.GenTestUserSig(userId);
            }
            return data;
        }

        public object GetUserSignsAsnyc(string userId)
        {
            var usign = "";
            if (!userId.IsNullOrEmpty())
            {
                usign = GenerateTestUserSig.GenTestUserSig(userId);
            }

            int aId = GenerateTestUserSig.SDKAPPID;

            var obj = new
            {
                SdkAppID = aId,
                UserSig = usign
            };

            return obj;
        }

        #endregion

        #region//私有方法

        /// <summary>
        /// 获取OLV列表
        /// </summary>
        /// <returns></returns>
        public List<OnLinkUserDTO> GetOLUserList()
        {
            List<OnLinkUserDTO> csList = new List<OnLinkUserDTO>();
            var cache = _serviceProvider.GetService<IDistributedCache>();
            var jstr = cache.GetString("OLinkUserList");
            Log.Information("OLinkUserList:{0}", jstr);
            if (!jstr.IsNullOrEmpty())
            {
                csList = JsonConvert.DeserializeObject<List<OnLinkUserDTO>>(jstr);
                csList = csList.Where(s => s.UserType == 1).ToList();

            }
            else
            {
                csList = new List<OnLinkUserDTO>();
            }

            return csList;
        }


        /// <summary>
        /// 获取OLV列表
        /// </summary>
        /// <returns></returns>
        public List<CServiceDTO> GetOLSUserList()
        {
            List<CServiceDTO> csList = new List<CServiceDTO>();
            var cache = _serviceProvider.GetService<IDistributedCache>();
            var jstr = cache.GetString("OCSUserList");
            Log.Information("OCSUserList:{0}", jstr);
            if (!jstr.IsNullOrEmpty())
            {
                csList = JsonConvert.DeserializeObject<List<CServiceDTO>>(jstr);
                csList = csList.ToList();

            }
            else
            {
                csList = new List<CServiceDTO>();
            }

            return csList;
        }

        /// <summary>
        /// 清楚OLVS
        /// </summary>
        public void ClearOLVSUserList()
        { 
            var csList = new List<CServiceDTO>();
            var cache = _serviceProvider.GetService<IDistributedCache>();
            cache.SetString("OCSUserList", csList.ToJson());
        }


        /// <summary>
        /// 移除OLV
        /// </summary>
        /// <param name="uIds"></param>
        public void DELOLUser(List<string> uIds)
        {
            List<OnLinkUserDTO> csList = new List<OnLinkUserDTO>();
            var cache = _serviceProvider.GetService<IDistributedCache>();
            var jstr = cache.GetString("OLinkUserList");
            if (!jstr.IsNullOrEmpty())
            {
                csList = JsonConvert.DeserializeObject<List<OnLinkUserDTO>>(jstr);
                //移除对应人员
                foreach (var item in uIds)
                { 
                    var index = csList.FindIndex(s => s.UserType == 1 && s.UserId.Equals(item));
                    if (index >= 0)
                    {
                        csList.RemoveAt(index);
                    }
                }

                //保存在线人员
                cache.SetString("OLinkUserList", csList.ToJson());

            }
        }

        /// <summary>
        /// 清空OLV
        /// </summary>
        public void ClearOLVUser()
        {
            var cache = _serviceProvider.GetService<IDistributedCache>();
            List<OnLinkUserDTO> csList = new List<OnLinkUserDTO>();
            //保存在线人员
            cache.SetString("OLinkUserList", csList.ToJson());
        }

        /// <summary>
        /// 生成随机用户Id
        /// </summary>
        /// <returns></returns>
        private string GetUserId()
        {
            string id = "VSP";

            id += IdHelper.GetId();

            var aCount = Service.GetIQueryable<ChatRoom>().Where(x => x.UserId.Equals(id)).Count();
            if (aCount > 0)
            {
                GetUserId();
            }

            return id;
        }

        /// <summary>
        /// 获取客服Id
        /// </summary>
        /// <param name="uIds"></param>
        /// <param name="classId"></param>
        /// <returns></returns>
        private async Task<string>  GetCSUserId(List<string> uIds, int classId)
        {
            string csId = "";
           
            var rList = await(from a in Service.GetIQueryable<Base_User>()
                              join j in Service.GetIQueryable<ConsumeServer>().Where(h => h.ClassId == classId) on a.Id equals j.UserId
                              join k in Service.GetIQueryable<ChatRoomCSUser>().Where(m => m.State == true) on a.Id equals k.ConstmeServerId into ak
                              from k in ak.DefaultIfEmpty()
                              join b in Service.GetIQueryable<ChatRoom>().Where(x => x.ClassId == classId) on k.RoomId equals b.Id into ab
                              from b in ab.DefaultIfEmpty()
                              select new
                              {
                                  a.Id,
                                  a.RealName,
                                  j.HeadImg,
                                  RId = b.Id,
                                  RName = b.ChatRoot_Name
                              }).GroupBy(x => new
                              {
                                  x.Id,
                                  x.RealName,
                                  x.HeadImg
                              }).Select(m => new
                              {
                                  m.Key.Id,
                                  m.Key.RealName,
                                  m.Key.HeadImg,
                                  RCount = m.Count()
                              }).ToListAsync();

            if (rList.Count > 0)
            {
                if (uIds.Count > 0)
                {
                    var rsList1 = rList.Where(x => uIds.Contains(x.Id)).ToList();
                    if (rsList1.Count > 0)
                    {
                        int minRCount1 = rsList1.Min(s => s.RCount);
                        csId = rList.Where(s => s.RCount == minRCount1).OrderBy(x => Guid.NewGuid()).FirstOrDefault().Id;
                    }
                }

                if (csId.IsNullOrEmpty())
                {
                    int minRCount = rList.Min(s => s.RCount);
                    csId = rList.Where(s => s.RCount == minRCount).OrderBy(x => Guid.NewGuid()).FirstOrDefault().Id;
                }
            }


            return csId;
        }

        /// <summary>
        /// 刷新客服未读消息数量
        /// </summary>
        private  async Task  SendCSUnReadNum(string CSUserId,int ClassId)
        {
            //获取房间未读消息
            int uReadCount = (from a in Service.GetIQueryable<ChatContent>().Where(m => m.ReceiverId.Equals(CSUserId) && m.ReadState == false)
                              join b in Service.GetIQueryable<ChatRoom>().Where(m => m.ClassId.Equals(ClassId)) on a.RoomId equals b.Id
                              select a).Count();

            Log.Information("SendCSUnReadNum=>group = {0}, type = {1}, uReadCount:{2}", "CS" + CSUserId, "UserUnread",  uReadCount);
            await  _messageHub.Clients.Groups("CS" + CSUserId).SendAsync("UserUnread", uReadCount);
        }

       /// <summary>
       /// 刷新客服房间列表
       /// </summary>
       /// <param name="CSUserId"></param>
       /// <param name="ClassId"></param>
       /// <returns></returns>
        private async Task UpdateCSRoomList(string CSUserId, int ClassId)
        {
            

            var list = await (from a in Service.GetIQueryable<ConsumeServer>().Where(h => h.ClassId == ClassId && h.UserId.Equals(CSUserId))
                        join k in Service.GetIQueryable<ChatRoomCSUser>().Where(m => m.State == true) on a.UserId equals k.ConstmeServerId
                        join b in Service.GetIQueryable<ChatRoom>().Where(x => x.ClassId == ClassId) on k.RoomId equals b.Id
                        join c in Service.GetIQueryable<BTB_StaffUser>() on b.UserId equals c.id into bc
                        from c in bc.DefaultIfEmpty()
                        select new { 
                            RId = b.Id,
                            RName = b.ChatRoot_Name,
                            UId = b.UserId,
                            UHeadImg = c.HeadPortrait,
                            UheadType = c.HeadType,
                            UName = c.NickName 
                        }).ToListAsync();

            List<SRoomDTO> dList = new List<SRoomDTO>();
            foreach (var item in list)
            {
                SRoomDTO rModel = new SRoomDTO();
                rModel.RoomId = item.RId;
                if (item.UName.IsNullOrEmpty())
                {
                    rModel.UserId = "USE" + item.UId;
                    rModel.RoomName = "游客"+item.UId.Substring(item.UId.Length - 5);
                    rModel.HeadType = 1;
                    rModel.HeadImg = userDefaultHeadImg;
                }
                else
                {
                    rModel.UserId = "USE" + item.UId;
                    rModel.RoomName = item.UName;
                    rModel.HeadImg = item.UHeadImg.IsNullOrEmpty() ? userDefaultHeadImg : item.UHeadImg;
                    rModel.HeadType = item.UHeadImg.IsNullOrEmpty() ? 1 : item.UheadType;
                   
                }

                //获取房间最新消息
                var message = await Service.GetIQueryable<ChatContent>().Where(x => x.RoomId.Equals(item.RId)).OrderByDescending(m => m.CreateTime).FirstOrDefaultAsync();
                if(!message.IsNullOrEmpty())
                {
                    rModel.MSTime = message.CreateTime;
                    rModel.messageType = message.MessageType;
                    rModel.NewMassage = message.MessageContent;
                }

                //获取房间客服未读消息数量
                rModel.MSCount =  Service.GetIQueryable<ChatContent>().Where(x => x.RoomId.Equals(item.RId) && x.ReadState == false && x.ReceiverId.Equals(CSUserId)).Count();
                dList.Add(rModel);
            }

            Log.Information("UpdateCSRoomList=> group ={0}, type = {1},dataCount = dList:{2}", "CS" + CSUserId, "StaffRoomList", dList.Count);
            await _messageHub.Clients.Groups("CS" + CSUserId).SendAsync("StaffRoomList", dList);
        }

        /// <summary>
        /// 刷新客服房间未读消息列表
        /// </summary>
        /// <param name="CSUserId"></param>
        /// <param name="ClassId"></param>
        /// <param name="RoomId"></param>
        /// <returns></returns>
        private async Task UpdateCSMessageList(string CSUserId, int ClassId, string RoomId, string msId)
        {
            TMessageDTO res = new TMessageDTO();
            res.MList = new List<SMessageDTO>();

            if (msId.IsNullOrEmpty())
            {
                #region//获取所有未读消息
                var list = await (from a in Service.GetIQueryable<ConsumeServer>().Where(h => h.ClassId == ClassId && h.UserId.Equals(CSUserId))
                                  join k in Service.GetIQueryable<ChatRoomCSUser>().Where(m => m.State == true) on a.UserId equals k.ConstmeServerId
                                  join b in Service.GetIQueryable<ChatRoom>().Where(x => x.ClassId == ClassId && x.Id.Equals(RoomId)) on k.RoomId equals b.Id
                                  join c in Service.GetIQueryable<BTB_StaffUser>() on b.UserId equals c.id into bc
                                  from c in bc.DefaultIfEmpty()
                                  join d in Service.GetIQueryable<ChatContent>().Where(x => x.ReadState == false && x.ReceiverId.Equals(CSUserId)) on b.Id equals d.RoomId
                                  select new
                                  {
                                      RId = b.Id,
                                      RName = b.ChatRoot_Name,
                                      UId = b.UserId,
                                      UHeadImg = c.HeadPortrait,
                                      UheadType = c.HeadType,
                                      UName = c.NickName,
                                      d.Id,
                                      d.CreateTime,
                                      d.SenderType,
                                      d.MessageType,
                                      d.MessageContent,
                                      d.MassageName,
                                      d.VState,
                                      d.MessageSize,
                                  }).OrderBy(m => m.CreateTime).ToListAsync();

                if (list.Count > 0)
                {
                    res.STime = list[0].CreateTime;

                    foreach (var item in list)
                    {
                        SMessageDTO MDTO = new SMessageDTO();
                        MDTO.Id = item.Id;
                        MDTO.userType = item.SenderType;
                        if (item.UName.IsNullOrEmpty())
                        {
                            MDTO.nickName = "游客"+item.UId.Substring(item.UId.Length - 6);
                            MDTO.headType = 1;
                            MDTO.headPortrait = userDefaultHeadImg;
                        }
                        else
                        {
                            MDTO.nickName  = item.UName;
                            MDTO.headType = item.UheadType;
                            MDTO.headPortrait = item.UHeadImg;
                        }
                        MDTO.messageType = item.MessageType;
                        MDTO.messageContent = item.MessageContent;
                        MDTO.createTime = item.CreateTime;
                        MDTO.createTimes =  MDTO.createTime.ToString("yyyy年MM月dd日 HH:mm:ss");
                        MDTO.MessageName = item.MassageName;
                        MDTO.MessageSize = item.MessageSize;
                        MDTO.vstate = item.VState;

                        res.MList.Add(MDTO);
                    }

                }
                else
                {
                    res.STime = DateTime.Now;
                }


                #endregion
            }
            else
            {
                var list = await (from a in Service.GetIQueryable<ConsumeServer>().Where(h => h.ClassId == ClassId && h.UserId.Equals(CSUserId))
                                  join k in Service.GetIQueryable<ChatRoomCSUser>().Where(m => m.State == true) on a.UserId equals k.ConstmeServerId
                                  join b in Service.GetIQueryable<ChatRoom>().Where(x => x.ClassId == ClassId) on k.RoomId equals b.Id
                                  join c in Service.GetIQueryable<BTB_StaffUser>() on b.UserId equals c.id into bc
                                  from c in bc.DefaultIfEmpty()
                                  join d in Service.GetIQueryable<ChatContent>().Where(x => x.ReadState == false && x.Id.Equals(msId) && x.ReceiverId.Equals(CSUserId)) on b.Id equals d.RoomId
                                  select new
                                  {
                                      RId = b.Id,
                                      RName = b.ChatRoot_Name,
                                      UId = b.UserId,
                                      UHeadImg = c.HeadPortrait,
                                      UheadType = c.HeadType,
                                      UName = c.NickName,
                                      d.Id,
                                      d.CreateTime,
                                      d.MessageType,
                                      d.MessageContent,
                                      d.SenderType,
                                      d.MassageName,
                                      d.VState,
                                      d.MessageSize,
                                  }).OrderBy(m => m.CreateTime).ToListAsync();

                if (list.Count > 0)
                {
                    res.STime = list[0].CreateTime;

                    foreach (var item in list)
                    {
                        SMessageDTO MDTO = new SMessageDTO();
                        MDTO.Id = item.Id;
                        MDTO.userType = item.SenderType;
                        if (item.UName.IsNullOrEmpty())
                        {
                            MDTO.nickName = "游客"+item.UId.Substring(item.UId.Length - 6);
                            MDTO.headType = 1;
                            MDTO.headPortrait = userDefaultHeadImg;
                        }
                        else
                        {
                            MDTO.nickName  = item.UName;
                            MDTO.headType = item.UheadType;
                            MDTO.headPortrait = item.UHeadImg;
                        }
                        MDTO.messageType = item.MessageType;
                        MDTO.messageContent = item.MessageContent;
                        //自动回复整理内容
                        if (MDTO.messageType == 11 && !item.MessageContent.IsNullOrEmpty())
                        {
                            var rpModel = (from a in Service.GetIQueryable<Base_AutoReply>().Where(s => s.Id.Equals(item.MessageContent))
                                           select new AutoReplyDTO
                                           {
                                               id = a.Id,
                                               contents = a.Contents,
                                               imgURL = a.ImgURL,
                                               link = a.ImgURL,
                                               childList = (from b in Service.GetIQueryable<Base_AutoReplyDetail>(true).Where(s => s.ReplyId.Equals(a.Id))
                                                            select new ReplyDetailDTO
                                                            {
                                                                id = b.Id,
                                                                contents = b.KeyNum,
                                                                imgURL = b.ImgUrl,
                                                                link = b.LinkUrl
                                                            }).ToList()
                                           }).FirstOrDefault();
                            if (!rpModel.IsNullOrEmpty())
                            {
                                MDTO.auto_Model = rpModel;
                            }


                        }
                        else if (MDTO.messageType == 12 && !item.MessageContent.IsNullOrEmpty())
                        {
                            var dtMdoel = Service.GetIQueryable<Base_AutoReplyDetail>().Where(x => x.Id.Equals(item.MessageContent)).Select(s => new Base_AutoReplyDetailDTOs
                            {
                                id = s.Id,
                                createTime = s.CreateTime,
                                replyId = s.ReplyId,
                                contents = s.Contents
                            }).FirstOrDefault();
                            if (!dtMdoel.IsNullOrEmpty())
                            {
                                MDTO.detailModel = dtMdoel;
                            }
                            else
                            {
                                MDTO.messageType = 0;
                                MDTO.messageContent = "抱歉，未找到对应内容";
                                Service.Update(MDTO);
                            }
                        }

                        MDTO.createTime = item.CreateTime;
                        MDTO.createTimes =  MDTO.createTime.ToString("yyyy年MM月dd日 HH:mm:ss");
                        MDTO.MessageName = item.MassageName;
                        MDTO.MessageSize = item.MessageSize;
                        MDTO.vstate = item.VState;

                        res.MList.Add(MDTO);
                    }

                }
                else
                {
                    res.STime = DateTime.Now;
                }
            }

            Log.Information("UpdateCSMessageList=>group = {0},type = {1},res.Coiunt:{2}", "CS" + CSUserId, "OnMessage", res.MList.Count);
            await _messageHub.Clients.Groups("CS" + CSUserId).SendAsync("OnMessage", res);

        }

        /// <summary>
        /// 刷新用户未读消息数量
        /// </summary>
        private async Task SendCUnReadNum(string UserId, int ClassId, string RoomId)
        {
            //获取房间未读消息
            int uReadCount = (from a in Service.GetIQueryable<ChatContent>().Where(m => m.ReceiverId.Equals(UserId) && m.ReadState == false)
                              join b in Service.GetIQueryable<ChatRoom>().Where(m => m.ClassId.Equals(ClassId) && m.Id.Equals(RoomId) ) on a.RoomId equals b.Id
                              select a).Count();

            Log.Information("SendCUnReadNum=>group = {0},type = {1}, uReadCount:{2}", "USE" + UserId, "UserUnread", uReadCount);
            await _messageHub.Clients.Groups("USE" + UserId).SendAsync("UserUnread", uReadCount);
        }

        /// <summary>
        /// 刷新用户房间未读消息列表
        /// </summary>
        /// <returns></returns>
        private async Task UpdateCUMessageList(string UserId, int ClassId, string RoomId)
        {
            Log.Information("进入刷新用户房间未读消息列表", "UserId:" + UserId, ",ClassId:"+ClassId, ",RoomId:"+RoomId);
            TMessageDTO res = new TMessageDTO();
            res.MList = new List<SMessageDTO>();
            if (!RoomId.IsNullOrEmpty())
            {
                #region//获取所有未读消息
                var list = await (from b in Service.GetIQueryable<ChatRoom>().Where(x => x.ClassId == ClassId)
                                  join k in Service.GetIQueryable<ChatRoomCSUser>().Where(m => m.State == true) on b.Id equals k.RoomId
                                  join a in Service.GetIQueryable<ConsumeServer>().Where(h => h.ClassId == ClassId) on k.ConstmeServerId equals a.UserId
                                  join c in Service.GetIQueryable<Base_User>() on a.UserId equals c.Id
                                  join d in Service.GetIQueryable<ChatContent>().Where(x => x.ReadState == false && x.ReceiverId.Equals(UserId)) on b.Id equals d.RoomId
                                  select new
                                  {
                                      RId = b.Id,
                                      RName = b.ChatRoot_Name,
                                      UId = c.Id,
                                      UHeadImg = a.HeadImg,
                                      UheadType = 1,
                                      UName = c.RealName,
                                      d.Id,
                                      d.CreateTime,
                                      d.MessageType,
                                      d.MessageContent,
                                      d.VState,
                                      d.MessageSize,
                                  }).OrderBy(m => m.CreateTime).ToListAsync();
                Log.Information("进入刷新用户房间未读消息列表", "list.Count:" + list.Count);
                if (list.Count > 0)
                {
                    res.STime = list[0].CreateTime;

                    foreach (var item in list)
                    {
                        var sPath = GetServicePath();
                        SMessageDTO MDTO = new SMessageDTO();
                        MDTO.Id = item.Id;
                        MDTO.userType = 1;
                        MDTO.nickName  = item.UName;
                        MDTO.headType = 1;
                        MDTO.headPortrait = sPath + "/" + (item.UHeadImg.IsNullOrEmpty() ? KfDefaultHeadImg:item.UHeadImg);
                        MDTO.messageType = item.MessageType;
                        MDTO.messageContent = item.MessageContent;
                        //自动回复整理内容
                        if ( MDTO.messageType == 11 && !item.MessageContent.IsNullOrEmpty())
                        {
                            Log.Information("进入刷新用户房间未读消息列表11", "list.Count:" + list.Count);
                            var rpModel = (from a in Service.GetIQueryable<Base_AutoReply>().Where(s => s.Id.Equals(item.MessageContent))
                                           select new AutoReplyDTO
                                           {
                                               id = a.Id,
                                               contents = a.Contents,
                                               imgURL = a.ImgURL,
                                               link = a.ImgURL,
                                               childList = (from b in Service.GetIQueryable<Base_AutoReplyDetail>(true).Where(s => s.ReplyId.Equals(a.Id))
                                                            select new ReplyDetailDTO
                                                            {
                                                                id = b.Id,
                                                                contents = b.KeyNum,
                                                                imgURL = b.ImgUrl,
                                                                link = b.LinkUrl
                                                            }).ToList()
                                           }).FirstOrDefault();
                            if (!rpModel.IsNullOrEmpty())
                            {
                                MDTO.auto_Model = rpModel;
                                MDTO.messageContent = rpModel.contents;
                            }

                           
                        }
                        else if ( MDTO.messageType == 12 && !item.MessageContent.IsNullOrEmpty())
                        {
                            Log.Information("进入刷新用户房间未读消息列表12", "list.Count:" + list.Count);
                            var dtMdoel = Service.GetIQueryable<Base_AutoReplyDetail>().Where(x => x.Id.Equals(item.MessageContent)).Select(s => new Base_AutoReplyDetailDTOs
                            {
                                id = s.Id,
                                createTime = s.CreateTime,
                                replyId = s.ReplyId,
                                contents = s.Contents
                            }).FirstOrDefault();
                            if (!dtMdoel.IsNullOrEmpty())
                            {
                                MDTO.detailModel = dtMdoel;
                            }
                            else
                            {
                                MDTO.messageType = 0;
                                MDTO.messageContent = "抱歉，未找到对应内容";
                                Service.Update(MDTO);
                            }
                        }


                        MDTO.createTime = item.CreateTime;
                        MDTO.createTimes =  MDTO.createTime.ToString("yyyy年MM月dd日 HH:mm:ss");
                        MDTO.MessageSize = item.MessageSize;
                        MDTO.vstate = item.VState;

                        res.MList.Add(MDTO);
                    }

                }
                else
                {
                    res.STime = DateTime.Now;
                  
                }

                #endregion
            }

            var ids = res.MList.Select(s => s.Id).ToList();
            if (ids.Count > 0)
            {
                await Service.UpdateAsync<ChatContent>(s => ids.Contains(s.Id), m => m.ReadState = true);
            }

            Log.Information("UpdateCUMessageList=> group = {0}, type = {1},  res:{2}", "USE" + UserId, "OnMessage", res.MList.Count);
 
           await _messageHub.Clients.Groups("USE" + UserId).SendAsync("OnMessage", res);
            
           
        }

        /// <summary>
        /// 盘古分词器进行自动回复
        /// </summary>
        /// <param name="input"></param>
        /// <param name="ATId"></param>
        /// <returns></returns>
        public async Task JQRAutoReply(ReplayInputDTO input, string ATId)
        {
            string ssId = "";
            if (ATId.IsNullOrEmpty())
            {
                //如果不是返回上级则匹配回复

                #region//问题收集
                var qCount = Service.GetIQueryable<Base_ARQuestion>().Where(x => x.QContent.Equals(input.ChatLog_Content)).Count();
                if (qCount == 0)
                {
                    Log.Information("进入问题收集。。。。");
                    Base_ARQuestion gMOdel = new Base_ARQuestion();
                    gMOdel.Id = IdHelper.GetId();
                    gMOdel.CreateTime = DateTime.Now;
                    gMOdel.CreatorId = _operator.UserId;
                    gMOdel.Deleted = false;
                    gMOdel.QContent = input.ChatLog_Content;
                    gMOdel.State = false;
                    gMOdel.InsertTime = DateTime.Now;
                    gMOdel.KeepOne = "";
                    gMOdel.KeepTwo = "";
                    Service.Insert(gMOdel);
                }
                #endregion

                #region//盘古分词
                var str = "";
                Analyzer analyzer = new PanGuAnalyzer();
                var srtr = new StringReader(input.ChatLog_Content);
                TokenStream tokenStream = analyzer.TokenStream("", srtr);
                Lucene.Net.Analysis.Token token = null;
                Log.Information("进入盘古分词。。。。");
                while ((token = tokenStream.Next()) != null)
                {
                    string word = token.TermText(); // token.TermText() 取得当前分词
                    str += word + " ";
                }
                #endregion

                #region//匹配关键词
                str = str.Trim();

                var searchResponse = _client.Search<Base_AutoReply>(s => s
                     .Index(IFName)
                     .Query(q => q
                        .Match(m => m
                            .Field(
                                f => f.KeyWord
                            )
                            .Query(str))
                        )

                     );

                var data = searchResponse.Documents.FirstOrDefault();
                Log.Information("匹配关键词data。。。。"+data);
                #endregion

                #region//回复内容
                //回复默认消息

                if (data == null)
                {
                    Log.Information("如果无法回复，回复默认内容。。。。");
                    #region //如果无法回复，回复默认内容
                    var mData = Service.GetIQueryable<Base_AutoReply>().Where(x => x.IsDefault).FirstOrDefault();
                    if (mData != null)
                    {
                        //有默认回复默认
                        DateTime ctheTime = DateTime.Now;

                        ChatContent scModel = new ChatContent();
                        scModel.Id = IdHelper.GetId();
                        scModel.CreatorId = "";
                        scModel.CreateTime = ctheTime;
                        scModel.Deleted = false;
                        scModel.MessageType = 11;
                        scModel.MessageContent =  mData.Id;
                        scModel.RoomId = input.ChatLog_RoomId;
                        scModel.ReadState = false;
                        scModel.SenderId = input.ChatRoot_StaffId;
                        scModel.ReceiverId = input.ChatRoot_UserId;
                        scModel.SenderType = 1;
                        scModel.MassageName = "";
                        scModel.MessageSize = "";
                        scModel.VState = true;

                        await Service.InsertAsync(scModel);

                        ssId = scModel.Id;

                    }
                    else
                    {
                        Log.Information("如果没设默认就回复抱歉。。。。");
                        //如果没设默认就回复抱歉
                        DateTime ctheTime = DateTime.Now;

                        ChatContent scModel = new ChatContent();
                        scModel.Id = IdHelper.GetId();
                        scModel.CreatorId = "";
                        scModel.CreateTime = ctheTime;
                        scModel.Deleted = false;
                        scModel.MessageType = 0;
                        scModel.MessageContent = "抱歉，暂时无法回答，请换个说法或换个问题进行咨询！";
                        scModel.RoomId = input.ChatLog_RoomId;
                        scModel.ReadState = false;
                        scModel.SenderId = input.ChatRoot_StaffId;
                        scModel.ReceiverId = input.ChatRoot_UserId;
                        scModel.SenderType = 1;
                        scModel.MassageName = "";
                        scModel.MessageSize = "";
                        scModel.VState = true;

                        await Service.InsertAsync(scModel);

                        ssId = scModel.Id;
                    }
                    #endregion

                }
                else
                {
                    //回复内容
                    DateTime ctheTime = DateTime.Now;

                    Log.Information("else 回复内容。。。。");
                    ChatContent scModel = new ChatContent();
                    scModel.Id = IdHelper.GetId();
                    scModel.CreatorId = "";
                    scModel.CreateTime = ctheTime;
                    scModel.Deleted = false;
                    scModel.MessageType = 11;
                    scModel.MessageContent = data.Id;
                    scModel.RoomId = input.ChatLog_RoomId;
                    scModel.ReadState = false;
                    scModel.SenderId = input.ChatRoot_StaffId;
                    scModel.ReceiverId = input.ChatRoot_UserId;
                    scModel.SenderType = 1;
                    scModel.MassageName = "";
                    scModel.MessageSize = "";
                    scModel.VState = true;

                    await Service.InsertAsync(scModel);

                    ssId = scModel.Id;


                    //移除之前内容
                    ASTDTO.ASTList.RemoveAll(x => x.UserId.Equals(input.ChatRoot_UserId) && x.StaffId.Equals(input.ChatRoot_StaffId));

                    //插入新内容
                    ASTModel dtModel = new ASTModel();
                    dtModel.StaffId = input.ChatRoot_StaffId;
                    dtModel.UserId = input.ChatRoot_UserId;
                    dtModel.ATId = data.Id;
                    var dstList = Service.GetIQueryable<Base_AutoReplyDetail>().Where(x => x.ReplyId.Equals(data.Id)).Select(x => x.Id).ToList();
                    dtModel.ATDId = dstList;
                    ASTDTO.ASTList.Add(dtModel);
                }

                #endregion
            }
            else
            {
                //根据Id获取内容
                var searchResponse = _client.Search<Base_AutoReply>(s => s
                      .Index(IFName)
                      .Query(q => q
                         .Match(m => m
                             .Field(
                                 f => f.Id
                             )
                             .Query(ATId))
                         )

                      );

                var tdata = searchResponse.Documents.FirstOrDefault();

                //有默认回复默认
                DateTime ctheTime = DateTime.Now;

                ChatContent scModel = new ChatContent();
                scModel.Id = IdHelper.GetId();
                scModel.CreatorId = "";
                scModel.CreateTime = ctheTime;
                scModel.Deleted = false;
                scModel.MessageType = 11;
                scModel.MessageContent = tdata.Id;
                scModel.RoomId = input.ChatLog_RoomId;
                scModel.ReadState = false;
                scModel.SenderId = input.ChatRoot_StaffId;
                scModel.ReceiverId = input.ChatRoot_UserId;
                scModel.SenderType = 1;
                scModel.MassageName = "";
                scModel.MessageSize = "";
                scModel.VState = true;

                await Service.InsertAsync(scModel);

                ssId = scModel.Id;

            }

            #region//刷新用户和客服房间消息

            //刷新用户消息列表
            await SendCUnReadNum(input.ChatRoot_UserId, input.ClassId, input.ChatLog_RoomId);

            //刷新用户房间消息列表
            await UpdateCUMessageList(input.ChatRoot_UserId, input.ClassId, input.ChatLog_RoomId);

            #endregion

        }
        #endregion

        /// <summary>
        /// 获取网站部署地址
        /// </summary>
        /// <returns></returns>
        private string GetServicePath()
        {
            var sPath = ConfigurationUtil.GetSection("ServiceURL");

            return sPath;
        }
    }
}
